package com.qhstudio.feelingnode.tools;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.os.AsyncTask;
import android.util.Log;

/**
 * 数据连接
 * 
 * @author xhwwzd
 *
 */
public class FellingClient extends AsyncTask<Void, Integer, Void> {
	public enum ClientType {
		POST, GET, UPLOAD
	}

	private ClientType clientType = ClientType.POST;
	private String url;
	private Map<String, String> map;
	private String data;
	private ClientListenter clientListenter;
	private ProgressListener progressListener;

	public FellingClient(String url) {
		setUrl(url);
	}

	public FellingClient(String url, ClientType type) {
		setUrl(url);
		setClientType(type);
	}

	public FellingClient(String url, ClientType type, Map<String, String> map) {
		setClientType(type);
		setUrl(url);
		setMap(map);
	}

	public <T> FellingClient(String url, ClientType type, T model) {
		setUrl(url);
		setClientType(type);
		Map<String, String> map = new HashMap<String, String>();

		for (Field temp : model.getClass().getFields()) {
			
			try {
				String key=temp.getName();
				debug(key);
				String value = temp.get(model).toString();
				debug(value);
				map.put(temp.getName(), temp.get(model).toString());
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		setMap(map);
	}

	public ClientType getClientType() {
		return clientType;
	}

	public void setClientType(ClientType clientType) {
		this.clientType = clientType;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Map<String, String> getMap() {
		return map;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	public ClientListenter getClientListenter() {
		return clientListenter;
	}

	public void setClientListenter(ClientListenter clientListenter) {
		this.clientListenter = clientListenter;
	}

	public ProgressListener getProgressListener() {
		return progressListener;
	}

	public void setProgressListener(ProgressListener progressListener) {
		this.progressListener = progressListener;
	}

	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
	}

	@Override
	protected Void doInBackground(Void... params) {
		// TODO Auto-generated method stub
		switch (clientType) {
		case GET:
			data = getType(getUrl(), getMap());
			break;
		case POST:
			data = postType(getUrl(), getMap());
			break;
		case UPLOAD:
			// data=uploadFile(srcPath, uploadUrl)
			break;
		}
		return null;
	}

	@Override
	protected void onPostExecute(Void result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		if (this.clientListenter != null) {
			this.clientListenter.backData(data);
		}
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		if (progressListener != null)
			progressListener.progress(Integer.parseInt(values.toString()));
	}

	protected String postType(String url, Map<String, String> map) {
		String res = "";
		try {
			HttpPost httpPost = new HttpPost(url);

			if (map != null) {
				List<NameValuePair> list = new ArrayList<NameValuePair>();
				for (Map.Entry<String, String> entry : map.entrySet()) {
					list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
				httpPost.setEntity(new UrlEncodedFormEntity(list, "utf-8"));
			}

			HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String strResult = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
				res = strResult;
			} else {
				debug("client-post-erro-" + httpResponse.getStatusLine().getStatusCode());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			debug("client-post-erro-client");
		}
		return res;
	}

	protected String getType(String url, Map<String, String> map) {
		String res = "";

		if (map != null) {
			String tempUrl = "";
			for (Map.Entry<String, String> entry : map.entrySet()) {
				tempUrl += "/" + entry.getKey() + "/" + entry.getValue();
			}
			url += tempUrl;
		}

		try {
			HttpGet httpRequest = new HttpGet(url);
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpResponse httpResponse = httpClient.execute(httpRequest);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String strResult = EntityUtils.toString(httpResponse.getEntity(), "utf-8").trim();
				res = strResult;
			} else {
				debug("client-get-erro-" + httpResponse.getStatusLine().getStatusCode());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			debug("client-get-erro-client");
		}
		return res;
	}

	/**
	 * 上传图片
	 * 
	 * @param srcPath
	 * @param uploadUrl
	 */
	protected String uploadFile(String srcPath, String uploadUrl) {
		String end = "\r\n";
		String twoHyphens = "--";
		String boundary = "******";
		String backData = "";
		try {
			URL url = new URL(uploadUrl);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();// http连接
			// 设置每次传输的流大小，可以有效防止手机因为内存不足崩溃
			// 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
			httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
			// 允许输入输出流
			httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setUseCaches(false);
			// 使用POST方法
			httpURLConnection.setRequestMethod("POST");
			httpURLConnection.setRequestProperty("Connection", "Keep-Alive");// 保持一直连接
			httpURLConnection.setRequestProperty("Charset", "UTF-8");// 编码
			httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);// POST传递过去的编码
			// httpURLConnection.setRequestProperty("name", userName);

			DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());// 输出流

			dos.writeBytes(twoHyphens + boundary + end);
			dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
					+ srcPath.substring(srcPath.lastIndexOf("/") + 1) + "\"" + end);
			dos.writeBytes(end);

			FileInputStream fis = new FileInputStream(srcPath);// 文件输入流，写入到内存中
			byte[] buffer = new byte[8192]; // 8k
			int count = 0;
			// 读取文件
			while ((count = fis.read(buffer)) != -1) {
				dos.write(buffer, 0, count);
			}
			fis.close();

			dos.writeBytes(end);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + end);

			dos.flush();

			InputStream is = httpURLConnection.getInputStream();// http输入，即得到返回的结果
			InputStreamReader isr = new InputStreamReader(is, "utf-8");
			BufferedReader br = new BufferedReader(isr);
			String result = br.readLine();
			backData = result;

			dos.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
			// setTitle(e.getMessage());

		}
		return backData;
	}

	/**
	 * 打印信息
	 * 
	 * @param log
	 */
	protected void debug(String log) {
		Log.e("info", log);
	}

	public interface ClientListenter {
		void backData(String data);
	}

	public interface ProgressListener {
		void progress(int p);
	}

}
